package com.zbkj.crmeb.store.service.impl;


import java.math.BigDecimal;
import java.text.ParseException;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.*;
import java.util.stream.Collectors;

import com.zbkj.crmeb.chant.model.ChannelActivity;
import com.zbkj.crmeb.chant.request.ActivityDetailsRequest;
import com.zbkj.crmeb.chant.service.ChannelActivityService;
import com.zbkj.crmeb.enums.OutOrderSourceEnum;
import com.zbkj.crmeb.member.model.ChannelMerchantAttribute;
import com.zbkj.crmeb.member.service.IChannelMerchantAttributeService;
import com.zbkj.crmeb.store.service.*;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.constants.Constants;
import com.constants.WeChatConstants;
import com.crmeb.core.exception.CrmebException;
import com.utils.CrmebUtil;
import com.utils.DateUtil;
import com.crmeb.core.utils.RedisUtil;
import com.utils.RestTemplateUtil;
import com.utils.WxPayUtil;
import com.utils.XmlUtil;
import com.zbkj.crmeb.chant.model.ChannelMerchant;
import com.zbkj.crmeb.chant.service.IChannelMerchantService;
import com.zbkj.crmeb.front.service.OrderService;
import com.zbkj.crmeb.merchant.admin.service.MerStoreOrderService;
import com.zbkj.crmeb.order.request.OutOrderInfoRequest;
import com.zbkj.crmeb.order.request.OutOrderRequest;
import com.zbkj.crmeb.payment.service.OrderPayService;
import com.zbkj.crmeb.payment.vo.hkwechat.HkPayPaymentQueryRequest;
import com.zbkj.crmeb.payment.vo.hkwechat.HkPayPaymentQueryResponse;
import com.zbkj.crmeb.payment.vo.wechat.AttachVo;
import com.zbkj.crmeb.payment.vo.wechat.CallbackVo;
import com.zbkj.crmeb.store.model.OrderInfoDelivery;
import com.zbkj.crmeb.store.model.StoreOrder;
import com.zbkj.crmeb.store.model.StoreOrderInfo;
import com.zbkj.crmeb.store.response.OutStoreOrderResponse;
import com.zbkj.crmeb.system.model.SystemConfig;
import com.zbkj.crmeb.system.service.SystemConfigService;
import com.zbkj.crmeb.task.order.OrderRefundByUser;

import lombok.extern.slf4j.Slf4j;

/**
* @author Mr.Zhang
* @description StoreOrderServiceImpl 接口实现
* @date 2020-05-28
*/
@Slf4j
@Service
public class OrderTaskServiceImpl implements OrderTaskService {
    //日志
    private static final Logger logger = LoggerFactory.getLogger(OrderRefundByUser.class);

    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private StoreOrderTaskService storeOrderTaskService;
    @Autowired
    private StoreOrderService storeOrderService;
    @Autowired
    private OrderService orderService;
    @Autowired
    private MerStoreOrderService merStoreOrderService;
    @Autowired
    private OrderInfoDeliveryService orderInfoDeliveryService;
    @Autowired
    private StoreOrderInfoService storeOrderInfoService;
    @Autowired
    private SystemConfigService systemConfigService;
    @Autowired
    private RestTemplateUtil restTemplateUtil;
    @Autowired
    private RestTemplate restTemplate;
    @Lazy
    @Autowired
    private OrderPayService orderPayService;
    @Autowired
    private IChannelMerchantService channelMerchantService;
    @Autowired
    private ChannelActivityService channelActivityService;
    @Autowired
    private StoreProductActivityService storeProductActivityService;
    @Autowired
    private IChannelMerchantAttributeService channelMerchantAttributeService;

    /**
     * 用户取消订单
     * @author Mr.Zhang
     * @since 2020-07-09
     */
    @Override
    public void cancelByUser() {
        String redisKey = Constants.ORDER_TASK_REDIS_KEY_AFTER_CANCEL_BY_USER;
        Long size = redisUtil.getListSize(redisKey);
        logger.info("OrderTaskServiceImpl.cancelByUser | size:" + size);
        if(size < 1){
            return;
        }
        for (int i = 0; i < size; i++) {
            //如果10秒钟拿不到一个数据，那么退出循环
            Object data = redisUtil.getRightPop(redisKey, 10L);
            if(null == data){
                continue;
            }
            try{
//                StoreOrder storeOrder = getJavaBeanStoreOrder(data);
                StoreOrder storeOrder = storeOrderService.getById(Integer.valueOf(data.toString()));
                boolean result = storeOrderTaskService.cancelByUser(storeOrder,true);
                if(!result){
                    redisUtil.lPush(redisKey, data);
                }
            }catch (Exception e){
                redisUtil.lPush(redisKey, data);
            }
        }
    }

    private StoreOrder getJavaBeanStoreOrder(Object data) {
        return JSONObject.toJavaObject(JSONObject.parseObject(data.toString()), StoreOrder.class);
    }

    /**
     * 用户退款申请
     * @author Mr.Zhang
     * @since 2020-07-09
     */
    @Override
    public void refundApply() {
        String redisKey = Constants.ORDER_TASK_REDIS_KEY_AFTER_REFUND_BY_USER;
        Long size = redisUtil.getListSize(redisKey);
        logger.info("OrderTaskServiceImpl.refundApply | size:" + size);
        if(size < 1){
            return;
        }
        for (int i = 0; i < size; i++) {
            //如果10秒钟拿不到一个数据，那么退出循环
            Object orderId = redisUtil.getRightPop(redisKey, 10L);
            if(null == orderId){
                continue;
            }
            try{
                StoreOrder storeOrder = storeOrderService.getById(Integer.valueOf(orderId.toString()));
                boolean result = storeOrderTaskService.refundApply(storeOrder);
                if(!result){
                    redisUtil.lPush(redisKey, orderId);
                }
            }catch (Exception e){
            	e.printStackTrace();
            	log.error(e.getMessage());
                redisUtil.lPush(redisKey, orderId);
            }
        }
    }

    /**
     * 完成订单
     * @author Mr.Zhang
     * @since 2020-07-09
     */
    @Override
    public void complete() {
        String redisKey = Constants.ORDER_TASK_REDIS_KEY_AFTER_COMPLETE_BY_USER;
        Long size = redisUtil.getListSize(redisKey);
        logger.info("OrderTaskServiceImpl.complete | size:" + size);
        if(size < 1){
            return;
        }
        for (int i = 0; i < size; i++) {
            //如果10秒钟拿不到一个数据，那么退出循环
            Object data = redisUtil.getRightPop(redisKey, 10L);
            if(null == data){
                continue;
            }
            try{
                StoreOrder storeOrder = getJavaBeanStoreOrder(data);
                boolean result = storeOrderTaskService.complete(storeOrder);
                if(!result){
                    redisUtil.lPush(redisKey, data);
                }
            }catch (Exception e){
                redisUtil.lPush(redisKey, data);
            }
        }
    }

    /**
     * 用户已收货
     * @author Mr.Zhang
     * @since 2020-07-09
     */
    @Override
    public void takeByUser() {
        String redisKey = Constants.ORDER_TASK_REDIS_KEY_AFTER_TAKE_BY_USER;
        Long size = redisUtil.getListSize(redisKey);
        logger.info("OrderTaskServiceImpl.takeByUser | size:" + size);
        if(size < 1){
            return;
        }
        for (int i = 0; i < size; i++) {
            //如果10秒钟拿不到一个数据，那么退出循环
            Object id = redisUtil.getRightPop(redisKey, 10L);
            if(null == id){
                continue;
            }
            try{
                StoreOrder storeOrder = storeOrderService.getByEntityOne(new StoreOrder().setId(Integer.valueOf(id.toString())));
                boolean result = storeOrderTaskService.takeByUser(storeOrder);
                if(!result){
                    redisUtil.lPush(redisKey, id);
                }
            }catch (Exception e){
                redisUtil.lPush(redisKey, id);
            }
        }
    }
    
    @Override
    public void takeBySystem() {
        String redisKey = Constants.ORDER_TASK_REDIS_KEY_AFTER_TAKE_BY_SYSTEM;
        Long size = redisUtil.getListSize(redisKey);
        logger.info("OrderTaskServiceImpl.takeBySystem | size:" + size);
        if(size < 1){
            return;
        }
        for (int i = 0; i < size; i++) {
            //如果10秒钟拿不到一个数据，那么退出循环
            Object id = redisUtil.getRightPop(redisKey, 10L);
            if(null == id){
                continue;
            }
            try{
                StoreOrder storeOrder = storeOrderService.getByEntityOne(new StoreOrder().setId(Integer.valueOf(id.toString())));
                boolean result = storeOrderTaskService.takeBySystem(storeOrder);
                if(!result){
                    redisUtil.lPush(redisKey, id);
                }
            }catch (Exception e){
                redisUtil.lPush(redisKey, id);
            }
        }
    }

    /**
     * 用户删除订单
     * @author Mr.Zhang
     * @since 2020-07-09
     */
    @Override
    public void deleteByUser() {
        String redisKey = Constants.ORDER_TASK_REDIS_KEY_AFTER_DELETE_BY_USER;
        Long size = redisUtil.getListSize(redisKey);
        logger.info("OrderTaskServiceImpl.deleteByUser | size:" + size);
        if(size < 1){
            return;
        }
        for (int i = 0; i < size; i++) {
            //如果10秒钟拿不到一个数据，那么退出循环
            Object data = redisUtil.getRightPop(redisKey, 10L);
            if(null == data){
                continue;
            }
            try{
                StoreOrder storeOrder = getJavaBeanStoreOrder(data);
                boolean result = storeOrderTaskService.deleteByUser(storeOrder);
                if(!result){
                    redisUtil.lPush(redisKey, data);
                }
            }catch (Exception e){
                redisUtil.lPush(redisKey, data);
            }
        }
    }


    /**
     * 未支付订单，超时系统自动取消订单
     * @param overMinutes
     */
    @Override
    public void cancelBySystem(int overMinutes) {

        //获取2021-01-28开始的所有未支付的订单
        QueryWrapper<StoreOrder> qw = new QueryWrapper<>();
        qw.lambda().eq(StoreOrder::getPaid, 0);
        qw.lambda().eq(StoreOrder::getStatus, 0);
        qw.lambda().eq(StoreOrder::getIsDel, 0);
        qw.lambda().eq(StoreOrder::getIsSystemDel, 0);
        try {
			qw.lambda().ge(StoreOrder::getCreateTime, DateUtils.parseDate("2021-01-28 00:00:00",Constants.DATE_FORMAT));
		} catch (ParseException e) {
			e.printStackTrace();
		}
        List<StoreOrder> list = storeOrderService.list(qw);
        /*//订单超市未支付撤销时间 默认60分钟
        String orderCancelTime = systemConfigService.getValueByKey(Constants.CONFIG_KEY_ORDER_CANCEL_TIME);
        if (StringUtils.isNotBlank(orderCancelTime)){
            overMinutes = Integer.parseInt(orderCancelTime);
        }*/
        //获取订单所有商户，判断商户是否有活动开启
        //订单创建时间超过1小时，则系统自动取消订单
        if (CollectionUtils.isNotEmpty(list)) {
            //查询商户设置的订单超时未支付撤销时间 默认120分钟
            List<String> merIdList = list.stream().map(storeOrder -> Constants.CONFIG_KEY_ORDER_CANCEL_TIME + "_" + storeOrder.getMerId()).collect(Collectors.toList());
            List<SystemConfig> systemConfigList = systemConfigService.list(Wrappers.lambdaQuery(SystemConfig.class).likeRight(SystemConfig::getName, Constants.CONFIG_KEY_ORDER_CANCEL_TIME + "_"));
            Map<Integer,SystemConfig> map = new HashMap<>();
            for(SystemConfig config : systemConfigList) {
            	String name = config.getName();
            	Integer merId = Integer.parseInt(name.substring(name.lastIndexOf("_") + 1, name.length()));
            	map.put(merId, config);
            }
            
            List<Integer> merIds = list.stream().map(StoreOrder::getMerId).collect(Collectors.toList());
            //查询商户活动订单取消时间
            List<ChannelMerchantAttribute> attributeList = channelMerchantAttributeService.list(Wrappers.lambdaQuery(ChannelMerchantAttribute.class).in(ChannelMerchantAttribute::getMerId,merIds));
            Map<Integer,Integer> merIdTimeMap = attributeList.stream().collect(Collectors.toMap(ChannelMerchantAttribute::getMerId,ChannelMerchantAttribute::getActivityOrderTime));
            //查询未支付订单详情
            List<Integer> orderIdList = list.stream().map(StoreOrder::getId).collect(Collectors.toList());
            List<StoreOrderInfo> orderInfoList = storeOrderInfoService.list(Wrappers.lambdaQuery(StoreOrderInfo.class)
                    .in(StoreOrderInfo::getOrderId,orderIdList));
            Map<Integer,List<Integer>> orderProductMap = orderInfoList.stream().collect(Collectors.groupingBy(StoreOrderInfo::getOrderId, Collectors.mapping(StoreOrderInfo::getProductId, Collectors.toList())));

            for (StoreOrder storeOrder: list) {
                List<ChannelActivity> activityList = new ArrayList<>();
                if (CollectionUtils.isNotEmpty(orderProductMap.get(storeOrder.getId()))){
                    ActivityDetailsRequest detailsRequest = new ActivityDetailsRequest();
                    detailsRequest.setMerId(storeOrder.getMerId());
                    detailsRequest.setEventTimeType(1);
                    detailsRequest.setCurrentTime(new Date());
                    detailsRequest.setProductIdList(orderProductMap.get(storeOrder.getId()));
                    //获取限制购买次数的活动及商品
                    activityList = channelActivityService.getActivityByProduct(detailsRequest);
                }

                //创建时间
                Date createTime = storeOrder.getCreateTime();
                if (null != createTime) {
                    //超时时间
//                    Date overTime = DateUtils.addHours(createTime, overHours);
                    Date overTime = DateUtils.addMinutes(createTime, Integer.parseInt(map.get(storeOrder.getMerId()).getValue()));
                    //判断商户订单商品详情中是否存在活动商品，存在活动商品时使用活动订单取消时间，否则时候普通订单取消时间
                    if (CollectionUtils.isNotEmpty(activityList) && merIdTimeMap.get(storeOrder.getMerId()) < Integer.parseInt(map.get(storeOrder.getMerId()).getValue())){
                        overTime = DateUtils.addMinutes(createTime, merIdTimeMap.get(storeOrder.getMerId()));
                    }
                    //当前时间
                    Date nowTime = DateUtil.nowDateTime();
                    if (DateUtil.compareDate(nowTime, overTime)) {
                        if (orderService.cancel(storeOrder)) {
                            logger.warn(storeOrder.getOrderId() + " ,该订单超过" + map.get(storeOrder.getMerId()).getValue() + "分钟, 系统自动取消订单成功！");
                        }
                    }
                }
            }
        }
    }

    @Override
    public void callBackOrder(List<StoreOrder> storeOrders) {
        for(StoreOrder storeOrder : storeOrders) {
            if(null == storeOrder.getMerId()) {
                continue;
            }
            List<StoreOrderInfo> storeOrderInfos = storeOrderInfoService.list(Wrappers.<StoreOrderInfo>lambdaQuery()
                    .eq(StoreOrderInfo :: getOrderId, storeOrder.getId())
                    );
            List<Integer> infoIds = storeOrderInfos.stream().map(StoreOrderInfo :: getId).collect(Collectors.toList());
            List<OrderInfoDelivery> orderInfoDeliverys2 = orderInfoDeliveryService.list(Wrappers.<OrderInfoDelivery>lambdaQuery()
                    .in(OrderInfoDelivery :: getOrderInfoId, infoIds)
                    );
            OutStoreOrderResponse outStoreOrderResponse = new OutStoreOrderResponse();
            outStoreOrderResponse.setOrderId(storeOrder.getOrderId());
            outStoreOrderResponse.setOrderInfoDeliverys(orderInfoDeliverys2);
            merStoreOrderService.sendBackOrder(storeOrder.getMerId(), outStoreOrderResponse, storeOrder.getBackCount());
        }
    }


    @Override
    public void orderPaymentStatusQuery(Integer merId) {
        LambdaQueryWrapper<StoreOrder> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(StoreOrder::getMerId,merId);
        queryWrapper.eq(StoreOrder::getPayType, Constants.PAY_TYPE_HK_PAY);//香港支付
        queryWrapper.eq(StoreOrder::getStatus,0);//待支付
        queryWrapper.eq(StoreOrder::getPaid,0);//未支付
        queryWrapper.eq(StoreOrder::getIsDel,0);
        queryWrapper.eq(StoreOrder::getIsSystemDel,0);
        queryWrapper.gt(StoreOrder::getCreateTime,DateUtil.addSecond(new Date(),65));//查询创建时间大于一个小时的订单
        List<StoreOrder> storeOrderList = storeOrderService.list(queryWrapper);
        for (StoreOrder storeOrder : storeOrderList){

            try {
                HkPayPaymentQueryRequest queryRequest = new HkPayPaymentQueryRequest();
                //获取商户号 密钥
                String mchId = getSysConfigValue(WeChatConstants.HK_PAY_MCH_ID,storeOrder.getMerId());
                String secretKey = getSysConfigValue(WeChatConstants.HK_PAY_SECRET_KEY,storeOrder.getMerId());

                queryRequest.setService(WeChatConstants.HK_PAY_TRADE_QUERY_SERVICE);
                queryRequest.setVersion("2.0");
                queryRequest.setCharset("UTF-8");
                queryRequest.setSign_type("MD5");
                queryRequest.setMch_id(mchId);
                queryRequest.setOut_trade_no(storeOrder.getOrderId());
                queryRequest.setNonce_str(getRandomStringByLength(32));
                //计算签名
                Map<String, Object> data = CrmebUtil.objectToMap(queryRequest);
                String sign = WxPayUtil.generateSignature(data, secretKey,"MD5");
                queryRequest.setSign(sign);
                logger.info("请求香港支付订单状态查询参数,param:{} ------- sign:{}", JSONObject.toJSONString(queryRequest), queryRequest.getSign());
                String param = XmlUtil.objectToXml(queryRequest);
                logger.info("请求香港支付订单状态查询参数,orderId:{},xml:{}",storeOrder.getOrderId(),param);
                String xml = restTemplateUtil.postXml(WeChatConstants.HK_PAY_API_URL, param);
                logger.info("请求香港支付订单状态查询参数响应,orderId:{},xml:{}",storeOrder.getOrderId(),xml);
                if (StringUtils.isBlank(xml)){
                    logger.info("香港支付订单状态查询接口调用失败");
                    continue;
                }
                //解析xml
                HashMap<String, Object> map = XmlUtil.xmlToMap(xml);
                HkPayPaymentQueryResponse queryResponse = CrmebUtil.mapToObj(map, HkPayPaymentQueryResponse.class);
                if (!"0".equals(queryResponse.getStatus())){
                    continue;
                }
                if (!"0".equals(queryResponse.getResult_code())){
                    continue;
                }
                if (!"SUCCESS".equals(queryResponse.getTrade_state())){
                    continue;
                }
                CallbackVo callbackVo = CrmebUtil.mapToObj(map, CallbackVo.class);
                AttachVo attachVo = JSONObject.toJavaObject(JSONObject.parseObject(callbackVo.getAttach()), AttachVo.class);
                logger.info("香港支付订单状态查询成功,callbackVo对象:{}",callbackVo);
                //判断openid
//                UserToken userToken = userTokenService.getUserIdByOpenId(callbackVo.getOpenid());
//                if(null == userToken || !userToken.getUid().equals(attachVo.getUserId())){
//                    用户信息错误
//                    throw new CrmebException("用户信息错误！");
//                }

                StoreOrder order = storeOrderService.getByOrderId(queryResponse.getOut_trade_no());
                if (order == null){
                    logger.info("香港支付订单状态查询失败,order:{}",order);
                    continue;
                }
                order.setOutOrderId(queryResponse.getTransaction_id());//平台订单号
                if(Constants.ORDER_STATUS_H5_UNPAID == order.getStatus() || Constants.ORDER_STATUS_H5_CANCEL == order.getStatus()){
                    Integer totalFee = queryResponse.getTotal_fee();
                    logger.info("香港支付订单状态查询订单金额,totalFee:{}",totalFee);
                    BigDecimal amount = new BigDecimal(totalFee);
                    if((order.getPayPrice().multiply(BigDecimal.TEN).multiply(BigDecimal.TEN)).compareTo(amount) == 0){
                        orderPayService.afterPaySuccess(order);

                    }else{
                        order.setMark("香港支付订单状态查询支付金额异常,请先检验一下订单");
                        orderPayService.afterPaySuccess(order);
                    }
                }else{
                    logger.info("订单状态异常 ======= 香港支付订单状态查询订单id:{}",queryResponse.getOut_trade_no());
                }

            }catch (Exception e){
                e.printStackTrace();
                logger.info("请求香香港支付订单状态查询异常,Exception:{}",e);
            }
        }

    }

    private String getRandomStringByLength(int length) {
        String base = "abcdefghijklmnopqrstuvwxyz0123456789";
        Random random = new Random();
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < length; i++) {
            int number = random.nextInt(base.length());
            sb.append(base.charAt(number));
        }
        return sb.toString();
    }

    private String getSysConfigValue(String key, Integer merId) {
        LambdaQueryWrapper<SystemConfig> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SystemConfig::getFormId,merId);
        queryWrapper.eq(SystemConfig::getName,key);
        queryWrapper.last("limit 1");
        SystemConfig systemConfig = systemConfigService.getOne(queryWrapper);
        if (systemConfig == null || StringUtils.isBlank(systemConfig.getValue())){
            throw new CrmebException("退款失败,密钥商户号等信息为空");
        }
        return systemConfig.getValue();
    }

    @Override
    public void imPutOrder() {
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        headers.add("Auth-Token", "FB2G3P");
        HttpEntity<JSONObject> formEntity = new HttpEntity<>(null, headers);
        // 获取两小时前到现在的订单
        Long milliSecondNow = LocalDateTime.now().toInstant(ZoneOffset.of("+8")).getEpochSecond();
        Long milliSecondOld = LocalDateTime.now().minusHours(2).toInstant(ZoneOffset.of("+8")).getEpochSecond();
        String urlTemplate = "http://api-merchant.intramirror.com/api/order/list?pageNo=1&pageSize=50&startCreated={}&endCreated={}&statusList=Pending";
        String url = String.format(urlTemplate, milliSecondOld, milliSecondNow);
        ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.GET, formEntity, String.class);

        if (HttpStatus.OK != response.getStatusCode()) {
            JSONObject message = JSONObject.parseObject(response.getBody());
            String errorMessage = message.getString("error");

            log.info("--------------- IM订单获取失败: {} ---------------", errorMessage);
        }
        JSONArray orders = JSONObject.parseObject(response.getBody()).getJSONObject("data").getJSONArray("list");
        log.info("--------------- IM拉取到新建订单数量: {} ---------------", orders.size());
        
        for(Object orderObj : orders) {
            JSONObject order = JSONObject.parseObject(JSONObject.toJSONString(orderObj));
            // 验证订单是否已存在
            StoreOrder storeOrder = storeOrderService.getByOrderId("OT" + order.getString("orderLineNum"));
            if(null != storeOrder){
                log.info("--------------- IM订单已存在,orderId:{} ---------------", order.getString("orderLineNum"));
                continue;
            }
            // 验证商户是否存在
            ChannelMerchant channelMerchant = channelMerchantService.getOne(Wrappers.<ChannelMerchant>lambdaQuery()
                    .eq(ChannelMerchant :: getChannelName, "IM")
                    .last("LIMIT 1")
                    );
            // 订单推送
            storeOrderService.pushOutOrder(buildImOrder(order), channelMerchant);
        }

    }
    
    private OutOrderRequest buildImOrder(JSONObject order) {
        JSONObject userInfo = order.getJSONObject("shipToAddress");
        
        OutOrderInfoRequest orderInfo = new OutOrderInfoRequest();
        orderInfo.setBarCode(order.getString("boutiqueId"));
        orderInfo.setSourceSkuId(order.getString("barcode"));
        orderInfo.setCartNum(order.getInteger("stock"));
        
        OutOrderRequest outOrderRequest = new OutOrderRequest();
        outOrderRequest.setOrderId(order.getString("orderLineNum"));
        outOrderRequest.setRealName(userInfo.getString("name"));
        outOrderRequest.setUserPhone(userInfo.getString("phone"));
        outOrderRequest.setAreaType(1);
        outOrderRequest.setUserAddress(userInfo.getString("province") + userInfo.getString("city") + userInfo.getString("area") + userInfo.getString("addr"));
        outOrderRequest.setTotalNum(order.getInteger("stock"));
        outOrderRequest.setCreateTime(new Date(order.getString("createdAt")));
        outOrderRequest.setPayTime(new Date(order.getString("createdAt")));
        outOrderRequest.setCreateName(userInfo.getString("name"));
        outOrderRequest.setProvince(userInfo.getString("province"));
        outOrderRequest.setCity(userInfo.getString("city"));
        outOrderRequest.setDistrict(userInfo.getString("area"));
        outOrderRequest.setDetail(userInfo.getString("addr"));
        outOrderRequest.setOutOrderSource(OutOrderSourceEnum.IM.getCode());
        return outOrderRequest;
    }
    
}
